package com.lzy.webapi.controller;

import com.lzy.base.apis.*;
import com.lzy.base.constants.Constants;
import com.lzy.base.dtos.SysRoleDto;
import com.lzy.base.dtos.SysUserAdminDto;
import com.lzy.base.utils.UserUtil;
import com.lzy.common.constants.BusinessType;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.utils.StringUtil;
import com.lzy.framework.tools.kv.KvClient;
import com.lzy.member.apis.MemberUserServiceApi;
import com.lzy.member.dtos.MemberUserDto;
import com.lzy.order.apis.UserAddressApi;
import com.lzy.product.common.constants.RedisPrefixConstants;
import com.lzy.product.dtos.ProductUserDto;
import com.lzy.sms.apis.MsgCodeApi;
import com.lzy.sms.constants.BusiTypeEnum;
import com.lzy.sms.dtos.CodeDTO;
import com.lzy.webapi.component.UserToken;
import com.lzy.webapi.constants.CommonConstants;
import com.lzy.webapi.response.MemberBaseResponse;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

public abstract class BaseController {
    private static final Logger LOGGER = LoggerFactory.getLogger(BaseController.class);

    @Resource
    private KvClient kvClient;
    @Autowired
    private MsgCodeApi msgCodeApi;
    @Autowired
    MemberUserServiceApi memberUserServiceApi;
    @Autowired
    private SysRoleServiceApi sysRoleServiceApi;
    @Autowired
    private InsuInfoServiceApi insuInfoServiceApi;

    public void storeSession(String key, Object value) {
        SecurityUtils.getSubject().getSession().setAttribute(key, value);
    }

    public UserToken isLogin(String token) {
        UserToken ut = kvClient.read(RedisPrefixConstants.TOKEN_KEY + token, UserToken.class);
        Ensure.that(ut == null).isFalse("00001014");
        return ut;
    }

    public UserToken getUserToken(String token) {
        UserToken ut = kvClient.read(RedisPrefixConstants.TOKEN_KEY + token, UserToken.class);
        return ut;
    }


    /**
     * 移动端登录成功后：创建token信息
     *
     * @return
     */
    public String createAndSaveToken(ProductUserDto userDto) {
        UserToken token = new UserToken();
        token.setCreateTime(new Date());
        token.setUserId(userDto.getId());
        token.setToken(StringUtil.getUUID());
        token.setLoginName(userDto.getLoginName());
        token.setUserName(userDto.getRealName());
        token.setDeptId(userDto.getDeptId());
        token.setIsClose(CommonConstants.TokenStatus.TOKEN_LOSE_NO);
        Integer minute = kvClient.read(RedisPrefixConstants.DIC + CommonConstants.TOKEN_TIME, Integer.class);
        kvClient.save(RedisPrefixConstants.TOKEN_KEY + token.getToken(), token, minute * 60);
        // 判断是否存在用户已经登录
        UserToken ut = kvClient.read(RedisPrefixConstants.TOKEN_KEY + userDto.getId(), UserToken.class);
        if (null != ut) {// 发现已经有登录过，可能在另外一台手机登录
            ut.setIsClose(CommonConstants.TokenStatus.TOKEN_T);// 设置被T标识
            kvClient.save(RedisPrefixConstants.TOKEN_KEY + ut.getToken(), ut, minute * 60);
        }
        kvClient.save(RedisPrefixConstants.TOKEN_KEY + userDto.getId(), token, minute * 60);
        return token.getToken();
    }

    /**
     * 移动端登出后：删除token信息
     *
     * @return
     */
    public void deleteToken(String token) {
        UserToken ut = isLogin(token);
        Ensure.that(ut).isNotNull("01000006");
        kvClient.delete(RedisPrefixConstants.TOKEN_KEY + ut.getToken());
    }

    /**
     * 校验验证码
     *
     * @param account
     * @param code
     * @return
     */
    public boolean verifyAuthInfo(String account, String code, Integer type) {
        CodeDTO codeDTO = new CodeDTO();
        codeDTO.setAuthTarget(account);
        Integer typeValue = new Integer(1);
        if (type.intValue() == 1) {
            typeValue = BusiTypeEnum.REGISTER_VERIFY.getVal();
        } else if (type.intValue() == 2) {
            typeValue = BusiTypeEnum.LOGIN_VERIFY.getVal();
        } else if (type.intValue() == 3) {
            typeValue = BusiTypeEnum.FIND_PWD_VERIFY.getVal();
        } else if (type.intValue() == 4) {
            typeValue = BusiTypeEnum.MODIFY_PAY_PWD_VERIFY.getVal();
        } else if (type.intValue() == 5) {
            typeValue = BusiTypeEnum.BIND_PHONE_VERIFY.getVal();
        } else if (type.intValue() == 8) {
            typeValue = BusiTypeEnum.OFFLINE_ONLINE_PHONE_VERIFY.getVal();
        }
        codeDTO.setAuthType(typeValue);
        codeDTO.setWay(com.lzy.sms.constants.CommonConstants.MediaWay.PHONE);
        codeDTO.setAuthCode(code);
        Boolean bool = msgCodeApi.verifyAuthInfo(codeDTO);
        return bool;
    }

    public String[] getCurrentUserStr() {
        SysUserAdminDto admin = (SysUserAdminDto) SecurityUtils.getSubject().getSession()
                .getAttribute(Constants.SYS_USER);
        Ensure.that(admin).isNotNull("-1");
        String[] strs = new String[5];
        strs[0] = admin.getId().toString();
        strs[1] = admin.getLoginName();
        strs[2] = admin.getRealName();
        strs[3] = getLoginUserRoleIds();
        strs[4] = getLoginUserRoleNames();
        return strs;
    }

    public String getLoginUserRoleIds() {
        Ensure.that(UserUtil.getCurrentUser()).isNotNull("-1");
        String roles = String.valueOf(SecurityUtils.getSubject().getSession().getAttribute(Constants.SYS_USER_ROLE));
        return roles;
    }

    public String getLoginUserRoleNames() {
        Ensure.that(UserUtil.getCurrentUser()).isNotNull("-1");
        String roles = String.valueOf(SecurityUtils.getSubject().getSession().getAttribute(Constants.SYS_USER_ROLE));
        Ensure.that(roles).isNotNull("-1");
        String[] roleIds = roles.split(",");
        String roleNames = "";
        for (int i = 0; i < roleIds.length; i++) {
            SysRoleDto sysRoleDto = sysRoleServiceApi.selectById(Long.parseLong(roleIds[i]));
            Ensure.that(sysRoleDto).isNotNull("-1");
            if (i == 0) {
                roleNames += sysRoleDto.getRlname();
            } else {
                roleNames += "," + sysRoleDto.getRlname();
            }
        }
        return roleNames;
    }

    /**
     * @Author:liyx
     * @Description:添加投保人信息
     * @Date:2017/7/5 15:01
     */

    public BigDecimal addInsurer(Integer policyNum, Integer dayNum) {
        //计算价格
        BigDecimal price = insuInfoServiceApi.getPrice(policyNum, dayNum);
        return price;
    }

    /**
     * @Author:liyx
     * @Description:只是为了代替getCurrentUserStr这个方法
     * @Date:2017/7/25 17:01
     */
    public String[] strs(String phone) {
        //用来代替后台的getCurrentUserStr();方法
        MemberUserDto userDto = memberUserServiceApi.findMemberByMobile(phone);
        String[] strs = new String[5];
        strs[0] = userDto.getId().toString();
        strs[1] = phone;
        strs[2] = userDto.getName();
        strs[3] = BusinessType.ShopType.DAY_TOUR.getCode() + "";
        strs[4] = BusinessType.ShopType.DAY_TOUR.getDesc();
        return strs;
    }

    /**
     * @Author:liyx
     * @Description:在没有session的状态下代替后台strs方法
     * @Date:2017/8/8 16:40
     */
    public String[] strs(String phone, String shopAppId) {
        //用来代替后台的getCurrentUserStr();方法
        String[] strs = new String[5];
        strs[0] = "1";
        strs[1] = phone;
        strs[2] = phone;
        strs[3] = shopAppId;
        strs[4] = BusinessType.ShopType.DAY_TOUR.desc(Long.valueOf(shopAppId));
        return strs;
    }

    /**
     * 以下四种情况下，统一返回个人信息对象：
     * 0、登录功能
     * 1、修改个人信息
     * 2、修改登录密码
     * 3、修改支付密码
     * 4、绑定手机号
     * 5、实名认证（待...）
     *
     * @param userDto
     * @return
     */
    public MemberBaseResponse getMemberBaseResponseByParam(ProductUserDto userDto, String token) {
        MemberBaseResponse response = new MemberBaseResponse();
        response.setLoginName(userDto.getLoginName());
        response.setRealName(userDto.getRealName());
        response.setSex(userDto.getSex());
        response.setAvatar(userDto.getAvatar());
        if (userDto != null) {
            response.setDeptId(userDto.getDeptId());
        }
        if (token == null || "".equals(token)) {
            token = this.createAndSaveToken(userDto);
        }
        response.setToken(token);
        return response;
    }

}
